home *** CD-ROM | disk | FTP | other *** search
/ Hottest 6 / Hottest 6 (1996)(PDSoft)[!].iso / software / fredfish / 1094.lha / Programs / Grocery / Grocery.c < prev    next >
C/C++ Source or Header  |  1995-03-20  |  48KB  |  1,507 lines

  1. /************************************************************************
  2. *
  3. *  Program:  Grocery.c
  4. *
  5. *  Author: Brian Gragg
  6. *
  7. *  Date:   11/29/92     version 0.1
  8. *           5/15/93     version 1.4 - added create meal menu option
  9. *          10/17/93     version 1.5 - added list scroll option & sort at print
  10. *           9/19/94     version 1.6 - fixed bug in meal generation option
  11. *            3/18/95     version 1.7 - moved about requester to grocery screen
  12. *
  13. *************************************************************************/
  14.  
  15. #define  DATAFILE    "Grocery.data"
  16. #define  BACKFILE    "Grocery.data.bak"
  17. #define  TEMPFILE    "t:groctmp"
  18. #define  MODEID      HIRESLACE_KEY
  19. #define  SWIDTH      640
  20. #define  SHEIGHT     400
  21. #define  SDEPTH      2
  22.  
  23. #define ASLLEFTEDGE 163
  24. #define ASLTOPEDGE  24
  25. #define ASLWIDTH    320
  26. #define ASLHEIGHT   200
  27.  
  28. #define MYGAD_ITEM     (0)
  29. #define MYGAD_AMOUNT   (1)
  30. #define MYGAD_SIZE     (2)
  31. #define MYGAD_GLIST    (3)
  32. #define MYGAD_ILIST    (4)
  33. #define MYGAD_MEALS    (5)
  34. #define MYGAD_EDIT     (6)
  35. #define MYGAD_DELETE   (7)
  36. #define MYGAD_SORT     (8)
  37. #define MYGAD_SORTNAME (9)
  38. #define MYGAD_AISLE   (10)
  39. #define MYGAD_ADD     (11)
  40. #define MAXGADGET     (12)  /* this should be 1 greater than last gadget id */
  41.  
  42. #define NOITEM         65535
  43. #define OPEN           1
  44. #define SAVE           2
  45.  
  46. #include <stdlib.h>
  47. #include <stdio.h>
  48. #include <string.h>
  49. #include <math.h>
  50. #include <time.h>
  51. #include <ctype.h>
  52. #include <exec/types.h>
  53. #include <exec/memory.h>
  54. #include <exec/lists.h>
  55. #include <exec/nodes.h>
  56. #include <dos/dos.h>
  57. #include <libraries/asl.h>
  58. #include <intuition/intuition.h>
  59. #include <intuition/screens.h>
  60. #include <intuition/gadgetclass.h>
  61. #include <libraries/gadtools.h>
  62. #include <intuition/intuitionbase.h>
  63. #include <graphics/gfx.h>
  64. #include <graphics/gfxbase.h>
  65. #include <libraries/dos.h>
  66.  
  67. #include <clib/utility_protos.h>
  68. #include <clib/alib_protos.h>
  69. #include <clib/exec_protos.h>
  70. #include <clib/dos_protos.h>
  71. #include <clib/intuition_protos.h>
  72. #include <clib/graphics_protos.h>
  73. #include <clib/gadtools_protos.h>
  74. #include <clib/asl_protos.h>
  75.  
  76. /* Use SAS/C 6.0 ability to open libraries for you !! */
  77. extern struct Library         *DOSBase;
  78. extern struct Library         *GadToolsBase;
  79. extern struct Library         *AslBase;
  80. extern struct IntuitionBase   *IntuitionBase;
  81. extern struct GfxBase         *GfxBase;
  82. extern struct Library         *SysBase;
  83. extern struct Library         *UtilityBase;
  84.  
  85. struct EasyStruct myES = {
  86.     sizeof(struct EasyStruct), 0, "GroceryList",
  87.     "%s",
  88.     "OK",
  89. };
  90.  
  91.  
  92. struct Screen *myscreen      = NULL;
  93. struct Window *window        = NULL;
  94. struct Menu   *menuStrip     = NULL;
  95. struct APTR   *my_VisualInfo = NULL;
  96. struct Gadget *glist         = NULL;
  97. struct List   *ItemList      = NULL;
  98. struct List   *GrocList      = NULL;
  99. struct List   *MealList      = NULL;
  100. struct List   *AislList      = NULL;
  101. struct Gadget *mygad[MAXGADGET];
  102. struct NewGadget ng;
  103.  
  104. #define NAMENODE_ID    100     /* The type of "NameNode" */
  105. #define MEALNODE_ID    101     /* The type of "MealNode" */
  106.  
  107. struct NameNode {
  108.    struct  Node nn_Node;       /* System Node structure            */
  109.    UBYTE   nn_Item[30];        /* The item (equals the node name)  */
  110.    UBYTE   nn_Size[10];        /* standard size (ie lbs, oz, etc)  */
  111.    UBYTE   nn_Amount[10];      /* usual amount                     */
  112.    WORD    nn_Aisle;           /* the aisle number where it's found*/
  113.    UBYTE   nn_LongName[80];    /* the long name associated with the item */
  114.    WORD    nn_ListPos;         /* ordinal position in a list       */
  115. };
  116.  
  117. struct MealNode {
  118.    struct  Node nn_Node;       /* System Node structure            */
  119.    UBYTE   nn_Meal[30];        /* The meal (equals node name)      */
  120.    struct  List *nn_MealItem;  /* a sublist of items               */
  121. };
  122.    
  123. struct TextAttr Topaz80 = { "topaz.font", 8, 0, 0, };
  124.  
  125. struct NewMenu mynewmenu[] =
  126. {
  127.     { NM_TITLE, "Project",  0 , 0, 0, 0,},
  128.     { NM_ITEM,  "New",       "N", 0, 0, 0,},
  129.     { NM_ITEM,  "Open...",   "O", 0, 0, 0,},
  130.     { NM_ITEM,  NM_BARLABEL,  0 , 0, 0, 0,},
  131.     { NM_ITEM,  "Save",      "S", 0, 0, 0,},
  132.     { NM_ITEM,  "Save As...","A", 0, 0, 0,},
  133.     { NM_ITEM,  NM_BARLABEL,  0 , 0, 0, 0,},
  134.     { NM_ITEM,  "Print",     "P", 0, 0, 0,},
  135.     { NM_ITEM,  NM_BARLABEL,  0 , 0, 0, 0,},
  136.     { NM_ITEM,  "About",      0 , 0, 0, 0,},
  137.     { NM_ITEM,  NM_BARLABEL,  0 , 0, 0, 0,},
  138.     { NM_ITEM,  "Quit",      "Q", 0, 0, 0,},
  139.     { NM_TITLE, "Meals",      0 , 0, 0, 0,},
  140.     { NM_ITEM,  "Create Meal","M", 0, 0, 0,},
  141.  };    
  142.  
  143. char savefilename[256];
  144. char aislename[30][22];
  145. char aisleId[30]; 
  146. WORD pens[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ~0};
  147. UWORD currentAisle = NOITEM;
  148. UWORD currentGroc  = NOITEM;
  149. far char buffer[256], buf[256];
  150.  
  151. #ifdef LATTICE
  152. int __chkabort(void) { return(0); } /* Disable Lattice CTRL/C handling */
  153. #endif
  154.  
  155. /* VERSION STRING */
  156. UBYTE vers[] = "\0$VER: Grocery 1.7";
  157. char screenname[80];
  158. char title[120];
  159.  
  160. /************ my protos *************/
  161. VOID cleanExit(char *);            /* clean up and close           */
  162. int doMenus(VOID);                 /* create menus                 */
  163. VOID handle_window_events(VOID);   /* deal with the IDCMP events   */
  164. VOID getWBPens(VOID);              /* get the workbench pens       */
  165. VOID setupGadgets(VOID);           /* setup the required gadgets   */
  166. VOID AddName(struct List *, UBYTE *, UBYTE *, UBYTE *, WORD);
  167. VOID AddItem(struct List *, UBYTE *, UBYTE *, UBYTE *, WORD);
  168. VOID AddAisle(struct List *, UBYTE *, WORD);
  169. struct List *AddMeal(struct List *, UBYTE *);
  170. VOID FreeMealNodes(struct List *);
  171. VOID FreeNameNodes(struct List *);
  172. VOID readData(VOID);               /* reads data from DATAFILE     */
  173. VOID newMeal(VOID);                /* saves the list as a meal in the database */
  174.  
  175.  
  176. /*************************************************************************/
  177.  
  178. void
  179. main(int argc, char *argv[])
  180. {
  181.    LONG screenTopBorder;
  182.    
  183.    /* Rely on SAS/C 6.0 to open the libraries for me */
  184.  
  185.    getWBPens();
  186.    
  187.    strcpy(title,&vers[7]);
  188.    strcat(title,"  - Brian Gragg March 1995");
  189.    strcpy(screenname,title);
  190.    
  191.    if (NULL == (myscreen = OpenScreenTags(NULL,
  192.              SA_Width,     SWIDTH,
  193.              SA_Height,    SHEIGHT,
  194.              SA_DisplayID, MODEID,
  195.              SA_Depth,     SDEPTH,
  196.              SA_Title,     screenname,
  197.              SA_Pens,      pens,
  198.              SA_ShowTitle, TRUE,
  199.              TAG_END))) 
  200.        cleanExit("Couldn't open screen.");
  201.    
  202.    readData();
  203.    setupGadgets();
  204.  
  205.    screenTopBorder = myscreen->WBorTop + myscreen->Font->ta_YSize +1;
  206.    if (NULL == (window = OpenWindowTags(NULL,
  207.              WA_Top,          screenTopBorder,
  208.              WA_Left,         0,
  209.              WA_Height,       myscreen->Height - screenTopBorder,
  210.              WA_Width,        myscreen->Width,
  211.              WA_CustomScreen, myscreen,
  212.              WA_NoCareRefresh,TRUE,
  213.              WA_IDCMP,        IDCMP_MENUPICK | IDCMP_MOUSEBUTTONS | 
  214.                                LISTVIEWIDCMP | IDCMP_REFRESHWINDOW,
  215.              WA_Gadgets,      glist,
  216.              WA_Activate,     TRUE,
  217.              WA_DetailPen,    3,
  218.              TAG_END)))
  219.        cleanExit("Couldn't open window.");
  220.    
  221.    
  222.    GT_RefreshWindow(window, NULL);
  223.    
  224.    ActivateGadget(mygad[MYGAD_ITEM],window,NULL);
  225.  
  226.    if (doMenus()) 
  227.        cleanExit("Couldn't create menu strip.");
  228.  
  229.    handle_window_events();
  230.    
  231.    cleanExit("");
  232. }
  233.  
  234.  
  235. /*********************************************************************
  236. *   cleanExit("message")
  237. *
  238. *      clean up and exit.  Print message before quiting.
  239. **********************************************************************/
  240.  
  241. VOID
  242. cleanExit(char *message)
  243. {
  244.    if (strlen(message) > 1)
  245.        EasyRequest(NULL, &myES, NULL, message);
  246.        
  247.    if (ItemList != NULL) {     FreeNameNodes(ItemList);
  248.                                FreeMem(ItemList, sizeof(struct List)); }
  249.    if (GrocList != NULL) {     FreeNameNodes(GrocList);
  250.                                FreeMem(GrocList, sizeof(struct List)); }
  251.    if (MealList != NULL) {     FreeMealNodes(MealList);
  252.                                FreeMem(MealList, sizeof(struct List)); }
  253.    if (AislList != NULL) {     FreeNameNodes(AislList);
  254.                                FreeMem(AislList, sizeof(struct List)); }
  255.    
  256.    if (menuStrip != NULL)      FreeMenus(menuStrip);
  257.    if (glist != NULL)          FreeGadgets(glist);
  258.    if (my_VisualInfo != NULL)  FreeVisualInfo(my_VisualInfo);
  259.  
  260.  
  261.    if (window != NULL)         CloseWindow(window);
  262.    if (myscreen != NULL)       CloseScreen(myscreen);
  263.  
  264.    /* Rely on SAS/C 6.0 to close libraries for me */ 
  265.    
  266.    exit(0);  
  267. }
  268.  
  269.  
  270. /*********************************************************************
  271. *   getWBPens()
  272. *
  273. *      get the colors from the workbench drawinfo structure
  274. **********************************************************************/
  275.  
  276. VOID
  277. getWBPens(VOID)
  278. {
  279.    UBYTE *pubScreenName = "Workbench";
  280.    int   i;
  281.    
  282.    struct Screen *pub_screen = NULL;
  283.    struct DrawInfo *screen_drawinfo = NULL;
  284.  
  285.    /* Get a lock on the Workbench screen */
  286.    pub_screen = LockPubScreen(pubScreenName);
  287.    if ( pub_screen == NULL )
  288.    {
  289.        EasyRequest(NULL, &myES, NULL, "Couldn't get a lock on workbench.");
  290.        for (i=0; i<4; i++)
  291.            pens[i] = i;
  292.        return;
  293.    }
  294.        
  295.    screen_drawinfo = GetScreenDrawInfo(pub_screen);
  296.    if ( screen_drawinfo == NULL)
  297.    {
  298.        UnlockPubScreen(pubScreenName,pub_screen);
  299.        EasyRequest(NULL, &myES, NULL, "Couldn't get workbench's drawinfo structure.");
  300.        for (i=0; i<4; i++)
  301.            pens[i] = i;
  302.        return;
  303.    }
  304.  
  305.    for (i=0; pens[i] != ~0; i++)
  306.       pens[i] = screen_drawinfo->dri_Pens[i];
  307.    
  308.    FreeScreenDrawInfo(pub_screen,screen_drawinfo);
  309.    UnlockPubScreen(pubScreenName,pub_screen);
  310. }
  311.  
  312. /*********************************************************************
  313. *   doMenus()
  314. *   return 0=ok  1=failed
  315. **********************************************************************/
  316.  
  317. int
  318. doMenus(VOID)
  319. {
  320.    if (NULL != (menuStrip = CreateMenus(mynewmenu, TAG_END)))
  321.    {
  322.        if (LayoutMenus(menuStrip, my_VisualInfo, TAG_END))
  323.        {
  324.            if (SetMenuStrip(window, menuStrip))
  325.            {
  326.                return(0);
  327.            }
  328.        }
  329.        FreeMenus(menuStrip);
  330.    }
  331.    return(1);
  332. }
  333.  
  334.  
  335. /*********************************************************************
  336. *   readData()
  337. *
  338. **********************************************************************/
  339.  
  340. VOID
  341. readData(VOID)
  342. {
  343.    FILE   *fileptr = NULL;      /* a pointer to a file handle */
  344.    char   *item, *amount, *size, meal[30];
  345.    long   place;
  346.    struct List *list;
  347.    char   *pointer;
  348.    int    i, j;
  349.       
  350.    GrocList = AllocMem(sizeof(struct List),MEMF_CLEAR);
  351.    ItemList = AllocMem(sizeof(struct List),MEMF_CLEAR);
  352.    MealList = AllocMem(sizeof(struct List),MEMF_CLEAR);
  353.    AislList = AllocMem(sizeof(struct List),MEMF_CLEAR);
  354.  
  355.    if ((GrocList == NULL) || (ItemList == NULL) || (MealList == NULL) || (AislList == NULL))
  356.        cleanExit("Out of memory allocating Lists.");
  357.        
  358.    NewList(GrocList);
  359.    NewList(ItemList);
  360.    NewList(MealList);
  361.    NewList(AislList);
  362.    
  363.    fileptr = fopen(DATAFILE,"r");
  364.    if ( fileptr == NULL )
  365.        cleanExit("Couldn't open data file.");
  366.    
  367.    while ((fgets(buffer,255,fileptr) != NULL) && (strlen(buffer) > 1))
  368.    {
  369.        if (buffer[0] != ';')
  370.        {
  371.            buffer[strlen(buffer)-1] = '\0';
  372.            i = atoi(&buffer[3]);  /* order id */
  373.            j = atoi(buffer);      /* aisle id */
  374.            aisleId[j] = i ;
  375.            strncpy(aislename[i],&buffer[6],13);
  376.            AddAisle(AislList,&buffer[6], (WORD)i); 
  377.        }
  378.    }
  379.  
  380.    while ((fgets(meal,29,fileptr) != NULL) && (strncmp(meal,"EXIT!",5)))
  381.    {
  382.        meal[strlen(meal)-1] = '\0';
  383.        list = AddMeal(MealList,meal);
  384.        
  385.        while ((fgets(buffer,255,fileptr) != NULL) && (strlen(buffer)>5) && 
  386.                    (strrchr(buffer,'`') != NULL))
  387.        {
  388.            pointer   =strrchr(buffer,'`');
  389.            pointer[0]='\0';
  390.            place     = atol(&pointer[1]);
  391.            pointer   =strrchr(buffer,'`');
  392.            pointer[0]='\0';
  393.            size      = &pointer[1];
  394.            pointer   =strrchr(buffer,'`');
  395.            pointer[0]='\0';
  396.            amount    = &pointer[1];
  397.            item      = buffer;
  398.  
  399.            AddName(list,item,amount,size,aisleId[place]);
  400.        }
  401.    }
  402.  
  403.    fgets(buffer,255,fileptr); /* read in blank line */
  404.    
  405.    
  406.    while ((fgets(buffer,255,fileptr) != NULL) && (strlen(buffer)>1))
  407.    {
  408.        pointer   =strrchr(buffer,'`');
  409.        pointer[0]='\0';
  410.        place     = atol(&pointer[1]);
  411.        pointer   =strrchr(buffer,'`');
  412.        pointer[0]='\0';
  413.        size      = &pointer[1];
  414.        pointer   =strrchr(buffer,'`');
  415.        pointer[0]='\0';
  416.        amount    = &pointer[1];
  417.        item      = buffer;
  418.        
  419.        AddName(ItemList,item,amount,size,aisleId[place]);
  420.    }
  421.  
  422.    fclose(fileptr);
  423. }
  424.  
  425.  
  426. /*********************************************************************
  427. *   setupGadgets()
  428. *
  429. **********************************************************************/
  430.  
  431. VOID
  432. setupGadgets(VOID)
  433. {
  434.    struct Gadget *gad;
  435.    
  436.    if (NULL == (my_VisualInfo = GetVisualInfo(myscreen, TAG_END)))
  437.        cleanExit("Couldn't GetVisualInfo.");
  438.  
  439.    gad = CreateContext(&glist);
  440.    
  441.    /** ITEM GADGET **/
  442.    ng.ng_LeftEdge   = 17;
  443.    ng.ng_TopEdge    = 348;
  444.    ng.ng_Width      = 215;
  445.    ng.ng_Height     = 21;
  446.    ng.ng_GadgetText = "Item";
  447.    ng.ng_VisualInfo = my_VisualInfo;
  448.    ng.ng_GadgetID   = MYGAD_ITEM;
  449.    ng.ng_TextAttr   = &Topaz80;
  450.    ng.ng_Flags      = PLACETEXT_BELOW;
  451.  
  452.    mygad[MYGAD_ITEM] = gad = CreateGadget(STRING_KIND, gad, &ng, 
  453.                    GA_TabCycle,      TRUE,
  454.                    GA_Immediate,     TRUE,
  455.                    STRINGA_ExitHelp, TRUE,
  456.                    TAG_END);
  457.  
  458.    /** AMOUNT GADGET **/
  459.    ng.ng_LeftEdge   = 236;
  460.    ng.ng_Width      = 84;
  461.    ng.ng_GadgetText = "Amount";
  462.    ng.ng_GadgetID   = MYGAD_AMOUNT;
  463.  
  464.    mygad[MYGAD_AMOUNT] = gad = CreateGadget(STRING_KIND, gad, &ng, 
  465.                    GA_TabCycle,    TRUE,
  466.                    GA_Immediate,   TRUE,
  467.                    TAG_END);   ng.ng_LeftEdge   = 17;
  468.  
  469.    /** UNITS GADGET **/
  470.    ng.ng_LeftEdge   = 324;
  471.    ng.ng_GadgetText = "Units";
  472.    ng.ng_GadgetID   = MYGAD_SIZE,
  473.  
  474.    mygad[MYGAD_SIZE] = gad = CreateGadget(STRING_KIND, gad, &ng, 
  475.                    GA_TabCycle,    TRUE,
  476.                    GA_Immediate,   TRUE,
  477.                    TAG_END);
  478.  
  479.    /** AISLE GADGET **/
  480.    ng.ng_LeftEdge   = 423;
  481.    ng.ng_TopEdge    = 316;
  482.    ng.ng_Width      = 185;
  483.    ng.ng_Height     = 60;
  484.    ng.ng_GadgetText = "Asile";
  485.    ng.ng_GadgetID   = MYGAD_AISLE;
  486.    
  487.    mygad[MYGAD_AISLE] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng, 
  488.                    GTLV_Labels,        AislList,
  489.                    GTLV_ScrollWidth,   18,
  490.                    GTLV_Top,           1,
  491.                    LAYOUTA_Spacing,    1,
  492.                    GTLV_ShowSelected,  NULL,
  493.                    TAG_END);
  494.  
  495.    /** MEALS GADGET **/
  496.    ng.ng_LeftEdge   = 423;
  497.    ng.ng_TopEdge    = 223;
  498.    ng.ng_Width      = 185;
  499.    ng.ng_Height     = 80;
  500.    ng.ng_GadgetText = "Meals";
  501.    ng.ng_GadgetID   = MYGAD_MEALS;
  502.    
  503.    mygad[MYGAD_MEALS] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng, 
  504.                    GTLV_Labels,        MealList,
  505.                    GTLV_ScrollWidth,   18,
  506.                    GTLV_Top,           0,
  507.                    LAYOUTA_Spacing,    1,
  508.                    TAG_END);
  509.  
  510.    /** ILIST GADGET **/
  511.    ng.ng_TopEdge    = 15;
  512.    ng.ng_Height     = 208;
  513.    ng.ng_GadgetText = "Items List";
  514.    ng.ng_GadgetID   = MYGAD_ILIST;
  515.    ng.ng_Flags      = PLACETEXT_ABOVE;
  516.    
  517.    mygad[MYGAD_ILIST] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng, 
  518.                    GTLV_Labels,        ItemList,
  519.                    GTLV_ScrollWidth,   18,
  520.                    GTLV_Top,           0,
  521.                    LAYOUTA_Spacing,    1,
  522.                    TAG_END);
  523.  
  524.  
  525.    /** GLIST GADGET **/
  526.    ng.ng_LeftEdge   = 17;
  527.    ng.ng_Width      = 390;
  528.    ng.ng_Height     = 292;
  529.    ng.ng_GadgetText = "Grocery List";
  530.    ng.ng_GadgetID   = MYGAD_GLIST;
  531.    
  532.    mygad[MYGAD_GLIST] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng, 
  533.                    GTLV_Labels,        GrocList,
  534.                    GTLV_ScrollWidth,   18,
  535.                    GTLV_Top,           0,
  536.                    LAYOUTA_Spacing,    1,
  537.                    GTLV_ShowSelected,  NULL,
  538.                    TAG_END);
  539.  
  540.    /** EDIT GADGET **/
  541.    ng.ng_LeftEdge   = 17;
  542.    ng.ng_TopEdge    = 310;
  543.    ng.ng_Width      = 56;
  544.    ng.ng_Height     = 20;
  545.    ng.ng_GadgetText = "EDIT";
  546.    ng.ng_GadgetID   = MYGAD_EDIT;
  547.    ng.ng_Flags      = PLACETEXT_IN;
  548.  
  549.    mygad[MYGAD_EDIT] = gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  550.  
  551.  
  552.    /** DELETE GADGET **/
  553.    ng.ng_LeftEdge   = 80;
  554.    ng.ng_GadgetText = "DELETE";
  555.    ng.ng_GadgetID   = MYGAD_DELETE;
  556.  
  557.    mygad[MYGAD_DELETE] = gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  558.  
  559.  
  560.    /** SORT BY AISLE GADGET **/
  561.    ng.ng_LeftEdge   = 143;
  562.    ng.ng_Width      = 94;
  563.    ng.ng_GadgetText = "AISLE SORT";
  564.    ng.ng_GadgetID   = MYGAD_SORT;
  565.  
  566.  
  567.    mygad[MYGAD_SORT] = gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  568.  
  569.    /** SORT BY NAME GADGET **/
  570.    ng.ng_LeftEdge   = 244;
  571.    ng.ng_GadgetText = "NAME SORT";
  572.    ng.ng_GadgetID   = MYGAD_SORTNAME;
  573.  
  574.    mygad[MYGAD_SORTNAME] = gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  575.  
  576.  
  577.    /** ADD GADGET **/
  578.    ng.ng_LeftEdge   = 345;
  579.    ng.ng_Width      = 62;
  580.    ng.ng_GadgetText = "ADDITEM";
  581.    ng.ng_GadgetID   = MYGAD_ADD;
  582.  
  583.    mygad[MYGAD_ADD] = gad = CreateGadget(BUTTON_KIND, gad, &ng, TAG_END);
  584.  
  585.    
  586.  
  587. }
  588.  
  589. /*********************************************************************
  590. *      NODE FUNCTIONS
  591. *
  592. *   AddName()  &  FreeNameNodes()  &  FindNode()  & alphaEnqueue
  593. *
  594. *      used to build and clear nodes from a list
  595. **********************************************************************/
  596.  
  597. VOID
  598. alphaEnqueue(struct List *list, struct Node *node)
  599. {                              /* inserts a node queued by pri then name */
  600.     struct Node *worknode;
  601.     BOOL   found = FALSE;
  602.  
  603.     worknode = list->lh_Head; /* First node */
  604.     while (worknode != NULL)
  605.     {
  606.         if ((worknode->ln_Pri < node->ln_Pri) ||
  607.             ((worknode->ln_Pri == node->ln_Pri) &&
  608.              (strcmp(worknode->ln_Name,node->ln_Name) > 0)))
  609.         {
  610.            Insert(list, node, worknode->ln_Pred);
  611.            found = TRUE;
  612.            break;
  613.         }
  614.         worknode = worknode->ln_Succ;
  615.     }
  616.     if ( found == FALSE )
  617.        AddTail(list,node);
  618. }
  619.  
  620.  
  621.  
  622. /* Allocate a NameNode structure, copy the given name into the structure,
  623.  * then add it the specified list. 
  624. */
  625.  
  626. VOID 
  627. AddName(struct List *list, UBYTE *item, UBYTE *amount, UBYTE *size, WORD aisle)
  628. {
  629.     struct NameNode *namenode;
  630.  
  631.     if (!( namenode = AllocMem(sizeof(struct NameNode),MEMF_CLEAR) ))
  632.         cleanExit("Out of memory adding a node.");
  633.  
  634.     strcpy(namenode->nn_Item,item);
  635.     strcpy(namenode->nn_Size,size);
  636.     strcpy(namenode->nn_Amount,amount);
  637.     namenode->nn_Aisle = aisle;
  638.     namenode->nn_Node.ln_Name = namenode->nn_Item;
  639.     namenode->nn_Node.ln_Type = NAMENODE_ID;
  640.     namenode->nn_Node.ln_Pri  = 0;
  641.     alphaEnqueue((struct List *)list,(struct Node *)namenode);
  642. }
  643.  
  644. VOID
  645. AddItem(struct List *list, UBYTE *item, UBYTE *amount, UBYTE *size, WORD aisle)
  646. {
  647.     struct NameNode *namenode;
  648.  
  649.     if (!( namenode = AllocMem(sizeof(struct NameNode),MEMF_CLEAR) ))
  650.         cleanExit("Out of memory adding a node.");
  651.  
  652.     strcpy(namenode->nn_Item,item);
  653.     strcpy(namenode->nn_Size,size);
  654.     strcpy(namenode->nn_Amount,amount);
  655.     namenode->nn_Aisle = aisle;
  656.     namenode->nn_Node.ln_Type = NAMENODE_ID;
  657.     namenode->nn_Node.ln_Pri  = 0;
  658.     sprintf(buffer,"%-18.18s %8.8s %-7.7s %-14.14s\0",namenode->nn_Item, namenode->nn_Amount,
  659.            namenode->nn_Size, aislename[namenode->nn_Aisle]);
  660.     strcat(namenode->nn_LongName,buffer);
  661.     namenode->nn_Node.ln_Name = namenode->nn_LongName;
  662.     AddTail((struct List *)list,(struct Node *)namenode);
  663. }
  664.  
  665. VOID 
  666. AddAisle(struct List *list, UBYTE *name, WORD aisle)
  667. {
  668.     struct NameNode *namenode;
  669.  
  670.     if (!( namenode = AllocMem(sizeof(struct NameNode),MEMF_CLEAR) ))
  671.         cleanExit("Out of memory adding a node.");
  672.  
  673.     strcpy(namenode->nn_Item,name);
  674.     namenode->nn_Aisle = aisle;
  675.     namenode->nn_Node.ln_Name = namenode->nn_Item;
  676.     namenode->nn_Node.ln_Type = NAMENODE_ID;
  677.     namenode->nn_Node.ln_Pri  = 40-aisle;
  678.     Enqueue((struct List *)list,(struct Node *)namenode);
  679. }
  680.  
  681.  
  682. struct List *
  683. AddMeal(struct List *list, UBYTE *meal)
  684. {
  685.     struct MealNode *mealnode;
  686.  
  687.     if (!( mealnode = AllocMem(sizeof(struct MealNode),MEMF_CLEAR) ))
  688.         cleanExit("Out of memory adding a meal.");
  689.  
  690.     strcpy(mealnode->nn_Meal,meal);
  691.     mealnode->nn_Node.ln_Name = mealnode->nn_Meal;
  692.     mealnode->nn_Node.ln_Type = MEALNODE_ID;
  693.     mealnode->nn_Node.ln_Pri  = 0;
  694.     if (!(mealnode->nn_MealItem = AllocMem(sizeof(struct List),MEMF_CLEAR)))
  695.        cleanExit("No memory for meal list.");
  696.     NewList(mealnode->nn_MealItem);
  697.     alphaEnqueue((struct List *)list,(struct Node *)mealnode);
  698.     return(mealnode->nn_MealItem);
  699. }
  700.  
  701.  
  702. /*
  703.  * Free the entire list, including the header.  The header is not updated
  704.  * as the list is freed.  This function demonstrates how to avoid
  705.  * referencing freed memory when deallocating nodes.
  706.  */
  707. VOID FreeNameNodes(struct List *list)
  708. {
  709.     struct NameNode *worknode;
  710.     struct NameNode *nextnode;
  711.  
  712.     worknode = (struct NameNode *)(list->lh_Head); /* First node */
  713.     while (nextnode = (struct NameNode *)(worknode->nn_Node.ln_Succ)) {
  714.         FreeMem(worknode,sizeof(struct NameNode));
  715.         worknode = nextnode;
  716.     }
  717. }
  718.  
  719. VOID FreeMealNodes(struct List *list)
  720. {
  721.     struct MealNode *worknode;
  722.     struct MealNode *nextnode;
  723.  
  724.     worknode = (struct MealNode *)(list->lh_Head); /* First node */
  725.     while (nextnode = (struct MealNode *)(worknode->nn_Node.ln_Succ)) 
  726.     {
  727.         FreeNameNodes(worknode->nn_MealItem);
  728.         FreeMem(worknode->nn_MealItem, sizeof(struct List));
  729.         FreeMem(worknode,sizeof(struct MealNode));
  730.         worknode = nextnode;
  731.     }
  732.  
  733. }
  734.  
  735.  
  736. struct Node *
  737. FindNode(struct List *list, int number)
  738. {
  739.    struct Node *node;
  740.    int    i;
  741.  
  742.    if (list->lh_TailPred == (struct Node *)list)
  743.        return(NULL);
  744.    else {
  745.        for (node = list->lh_Head, i=0; i<number ; node = node->ln_Succ, i++)
  746.            ;
  747.    return(node);
  748.    }
  749. }
  750.  
  751.  
  752. /*********************************************************************
  753. *   getFile(Prompt)
  754. *   
  755. *      gets a file using the ASL file requester & the prompt
  756. **********************************************************************/
  757.  
  758.  
  759. BPTR
  760. getFile(char *prompt,int type)
  761. {
  762.     struct FileRequester *fr;
  763.     static BYTE savefile[100] = "";
  764.     static BYTE savedir[255]  = "";
  765.     char doit[10];
  766.     ULONG fileflag;
  767.     long  mode;
  768.     BPTR  fh = -1L;
  769.  
  770.     if (type == OPEN)
  771.     { 
  772.        strcpy(doit,"OPEN");
  773.        fileflag = 0L;
  774.     }
  775.     else
  776.     {
  777.        strcpy(doit,"SAVE");
  778.        fileflag = FILF_SAVE;
  779.     }
  780.     
  781.     if (fr = (struct FileRequester *)
  782.          AllocAslRequestTags(ASL_FileRequest,
  783.              ASL_Hail,       (ULONG)prompt,
  784.              ASL_Height,     200,
  785.              ASL_Width,      320,
  786.              ASL_LeftEdge,   163,
  787.              ASL_TopEdge,    50,
  788.              ASL_OKText,     (ULONG)doit,
  789.              ASL_CancelText, (ULONG)"CANCEL",
  790.              ASL_Window,     window,
  791.              ASL_File,       savefile,
  792.              ASL_Dir,        savedir,
  793.              ASL_FuncFlags,  fileflag,
  794.              TAG_DONE))
  795.      {
  796.          if (AslRequest(fr,NULL))  
  797.          {
  798.              strcpy(savedir, fr->rf_Dir);
  799.              strcpy(savefile, fr->rf_File);
  800.  
  801.              /* setup filename and load it */             
  802.              strcpy(buffer,fr->rf_Dir);
  803.              if (AddPart(buffer,fr->rf_File,255))
  804.              {
  805.                 if (type == OPEN)
  806.                    mode = MODE_OLDFILE;
  807.                 else
  808.                    mode = MODE_NEWFILE;
  809.                 fh = Open(buffer,mode);
  810.                 strcpy(savefilename,buffer);
  811.                 sprintf(screenname,"%s    [FILE: %s]",title,fr->rf_File);
  812.                 ShowTitle(myscreen,TRUE);
  813.              }
  814.          }
  815.          else
  816.            fh = 0L;    /* CANCEL */
  817.          FreeAslRequest(fr);
  818.     }
  819.     return(fh);
  820. }
  821.  
  822.  
  823. /*********************************************************************
  824. *   Menu selection (NEW)
  825. *
  826. **********************************************************************/
  827.  
  828. VOID
  829. doNew(VOID)
  830. {
  831.    GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  832.        GTLV_Labels, ~0, TAG_DONE);
  833.    FreeNameNodes(GrocList);
  834.    FreeMem(GrocList, sizeof(struct List));
  835.    if (!(GrocList = AllocMem(sizeof(struct List),MEMF_CLEAR)))
  836.        cleanExit("No memory for Grocery list.");
  837.    NewList(GrocList);
  838.    GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  839.        GTLV_Labels, GrocList, TAG_DONE);
  840. }
  841.  
  842.  
  843. /*********************************************************************
  844. *   Menu selection (OPEN)
  845. *
  846. **********************************************************************/
  847.  
  848. VOID
  849. doOpen(VOID)
  850. {
  851.    BPTR   pfile;
  852.    char   *pointer;
  853.    char   *item, *amount, *size;
  854.    long   place = 0L;
  855.     
  856.    if (-1 == (pfile = getFile("Select Save Open:",OPEN)))
  857.    {
  858.        sprintf(buf,"Couldn't open file '%s'.",buffer);
  859.        EasyRequest(window, &myES, NULL, buf);
  860.    }
  861.    
  862.    doNew();
  863.  
  864.    GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  865.             GTLV_Labels, ~0, TAG_DONE);   
  866.  
  867.    while (FGets(pfile,buffer,255) != NULL)
  868.    {
  869.        pointer   =strrchr(buffer,'`');
  870.        pointer[0]='\0';
  871.        place     = atol(&pointer[1]);
  872.        pointer   =strrchr(buffer,'`');
  873.        pointer[0]='\0';
  874.        size      = &pointer[1];
  875.        pointer   =strrchr(buffer,'`');
  876.        pointer[0]='\0';
  877.        amount    = &pointer[1];
  878.        item      = buffer;
  879.        AddItem(GrocList,item,amount,size,aisleId[place]);
  880.    }
  881.    GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  882.             GTLV_Labels, GrocList, TAG_DONE);
  883.    
  884.    Close(pfile);
  885. }          
  886.  
  887. /*********************************************************************
  888. *   Menu selection (SAVE & SAVE AS)
  889. *
  890. **********************************************************************/
  891.  
  892. VOID
  893. doSave(VOID)
  894. {
  895.    BPTR   pfile;
  896.    struct NameNode *node;
  897.    int    i;
  898.  
  899.    if (GrocList->lh_TailPred == (struct Node *)GrocList)
  900.        return;  /* empty list */
  901.  
  902.    if (savefilename[0] == '\0')
  903.    {
  904.        pfile = getFile("Select Save File:",SAVE);
  905.        if (pfile == -1 )
  906.        {
  907.            sprintf(buf,"Couldn't open file '%s'\nIt may already exist.",buffer);
  908.            EasyRequest(window, &myES, NULL, buf);
  909.        }
  910.            
  911.        if (pfile == 0 )
  912.            return;
  913.    }
  914.    else
  915.    {
  916.        DeleteFile(savefilename);
  917.        if (-1 == (pfile = Open(savefilename,MODE_NEWFILE)))
  918.        {
  919.          sprintf(buffer,"Couldn't open file '%s'.",savefilename);
  920.          EasyRequest(window, &myES, NULL, buffer);
  921.        }
  922.    }
  923.    
  924.    if (pfile == -1) return;
  925.    
  926.    for (node=(struct NameNode *)GrocList->lh_Head ; 
  927.           node->nn_Node.ln_Succ ; 
  928.           node = (struct NameNode *)node->nn_Node.ln_Succ)
  929.    {   
  930.        for (i = 0; i < 30; i++)
  931.            if (aisleId[i] == node->nn_Aisle)
  932.                break;
  933.                
  934.        sprintf(buffer, "%s`%s`%s`%d\n", node->nn_Item, node->nn_Amount,
  935.             node->nn_Size, i);
  936.             
  937.        if (-1 == Write(pfile, buffer, strlen(buffer)))
  938.        {
  939.            EasyRequest(window, &myES, NULL, "Save File Failed.");
  940.            break;
  941.        }
  942.    }
  943.    strcpy(buf,screenname);
  944.    sprintf(screenname,"Saved to file: %s",savefilename);
  945.    ShowTitle(myscreen,TRUE);
  946.    strcpy(screenname,buf);
  947.        
  948.    Close(pfile);
  949. }
  950.  
  951.  
  952. /*********************************************************************
  953. *   Sort List 
  954. *               doSort(ID)   ID= MYGAD_SORT  or MYGAD_SORTNAME
  955. **********************************************************************/
  956.  
  957. VOID
  958. doSort(int ID)
  959. {
  960. struct NameNode *node, *nextnode;
  961. struct List *list;
  962.  
  963.       if (GrocList->lh_TailPred == (struct Node *)GrocList)
  964.           return;  /* empty list */
  965.       if (!(list = AllocMem(sizeof(struct List),MEMF_CLEAR)))
  966.           cleanExit("No memory for list.");
  967.       NewList(list);
  968.       GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  969.               GTLV_Labels, ~0, TAG_DONE);
  970.       
  971.       for (nextnode=node=(struct NameNode *)GrocList->lh_Head ; 
  972.              nextnode->nn_Node.ln_Succ ; node = nextnode)
  973.       {
  974.           nextnode = (struct NameNode *)node->nn_Node.ln_Succ;
  975.           Remove((struct Node *)node);
  976.           if (ID == MYGAD_SORT)
  977.               node->nn_Node.ln_Pri = 40-node->nn_Aisle;
  978.           else
  979.               node->nn_Node.ln_Pri = 0;
  980.           alphaEnqueue(list,(struct Node *)node);
  981.       }
  982.       FreeMem(GrocList, sizeof(struct List));
  983.       GrocList = list;
  984.       GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  985.               GTLV_Labels, GrocList, TAG_DONE);
  986.       currentGroc = NOITEM;
  987.       ActivateGadget(mygad[MYGAD_ITEM],window,NULL);
  988. }
  989.  
  990.  
  991. /*********************************************************************
  992. *   Menu selection (PRINT)
  993. *
  994. **********************************************************************/
  995.  
  996. VOID
  997. doPrint(VOID)
  998. {
  999.    BPTR   pfile;
  1000.    struct NameNode *node;
  1001.    char   line[70];
  1002.  
  1003.    doSort(MYGAD_SORT);
  1004.    
  1005.    if (GrocList->lh_TailPred == (struct Node *)GrocList)
  1006.        return;  /* empty list */
  1007.    
  1008.    if (!(pfile = Open( "PRT:", MODE_NEWFILE)))
  1009.        EasyRequest(window, &myES, NULL, "Could not access printer.");
  1010.    
  1011.    Write(pfile, "zw", 8L);    
  1012.    for (node=(struct NameNode *)GrocList->lh_Head;
  1013.         node->nn_Node.ln_Succ ; 
  1014.         node = (struct NameNode *)node->nn_Node.ln_Succ)
  1015.    {
  1016.        if (node->nn_Aisle == ((struct NameNode *)node->nn_Node.ln_Succ)->nn_Aisle)
  1017.            strcpy(line,"");
  1018.        else
  1019.            strcpy(line,"");
  1020.        
  1021.        sprintf(buffer,
  1022.            "%s%10.10s %-30.30s %-10.10s %-21.21s\n",
  1023.            line,node->nn_Amount, node->nn_Item,
  1024.            node->nn_Size, aislename[node->nn_Aisle]);
  1025.        if (-1 == Write(pfile, buffer, strlen(buffer)))
  1026.        {
  1027.            EasyRequest(window, &myES, NULL, "Printing Failed.");
  1028.            break;
  1029.        }
  1030.    }
  1031.    Write(pfile,"zw",8L);
  1032.    Close(pfile);
  1033.  
  1034.  
  1035. /*********************************************************************
  1036. *   node = findBestFit(string)
  1037. *
  1038. *      finds the item whose name best fist the string.
  1039. **********************************************************************/
  1040.  
  1041. struct NameNode *
  1042. findBestFit(char *namestring)
  1043. {
  1044.    struct NameNode *node;
  1045.    int    i = 0;
  1046.    
  1047.    for (node=(struct NameNode *)ItemList->lh_Head ; 
  1048.            node->nn_Node.ln_Succ, Stricmp(node->nn_Item,namestring)<0; 
  1049.            node = (struct NameNode *)node->nn_Node.ln_Succ, i++);
  1050.    node->nn_ListPos = i;
  1051.    return(node);
  1052. }
  1053.  
  1054.  
  1055. /*********************************************************************
  1056. *   getItem(node)
  1057. *
  1058. *      gets the info from the item and loads item,amount,size,location 
  1059. *          requesters
  1060. **********************************************************************/
  1061.  
  1062. VOID
  1063. getItem(struct NameNode *node)
  1064. {
  1065.    GT_SetGadgetAttrs(mygad[MYGAD_ITEM],window,NULL,
  1066.            GTST_String, node->nn_Item, TAG_DONE);
  1067.    GT_SetGadgetAttrs(mygad[MYGAD_AMOUNT],window,NULL,
  1068.            GTST_String, node->nn_Amount, TAG_DONE);
  1069.    GT_SetGadgetAttrs(mygad[MYGAD_SIZE],window,NULL,
  1070.            GTST_String, node->nn_Size, TAG_DONE);
  1071.    GT_SetGadgetAttrs(mygad[MYGAD_AISLE],window,NULL,
  1072.            GTLV_Selected, node->nn_Aisle, TAG_DONE);
  1073. /* turning this on will cause the item list to move the
  1074.    clicked on selection to the top each time.           
  1075.    GT_SetGadgetAttrs(mygad[MYGAD_ILIST],window,NULL,
  1076.            GTLV_Top, node->nn_ListPos, TAG_DONE);      
  1077. */
  1078.    ActivateGadget(mygad[MYGAD_AMOUNT],window,NULL);
  1079.    currentAisle = node->nn_Aisle;
  1080. }
  1081.  
  1082.  
  1083.  
  1084.  
  1085. /*********************************************************************
  1086. *   MEALS -> CREATE MEAL  menu option
  1087. *
  1088. **********************************************************************/
  1089.  
  1090.  
  1091. VOID 
  1092. newMeal(VOID)
  1093. {
  1094.    FILE   *fileptr = NULL;      /* a pointer to a file handle */
  1095.    FILE   *tempptr = NULL;
  1096.    struct List *list;
  1097.    struct NameNode *node;
  1098.    int i;
  1099.  
  1100.    struct EasyStruct yesno = {
  1101.        sizeof(struct EasyStruct), 0, "GroceryList",
  1102.        "%s",
  1103.        "OK|CANCEL",    
  1104.        };
  1105.  
  1106.    if (GrocList->lh_TailPred == (struct Node *)GrocList)
  1107.    {
  1108.        EasyRequest(window, &myES, NULL, "Grocery List empty.\nTo use this option, fill the grocery list with the\nitems in the meal and put the meal name\nin the ITEM box.  Then select CREATE MEAL");
  1109.        return;  /* empty list */
  1110.    }
  1111.  
  1112.    if (strlen(((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer) < 1)
  1113.    {
  1114.        EasyRequest(window, &myES, NULL, "Item Field empty.\nTo use this option, fill the grocery list with the\nitems in the meal and put the meal name\nin the ITEM box.  Then select CREATE MEAL");
  1115.        return;  /* empty list */
  1116.    }
  1117.  
  1118.    sprintf(buffer,"Copy current list to a meal item\ncalled %s?",
  1119.        ((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer);
  1120.    if (0L == EasyRequest(window, &yesno, NULL, buffer))
  1121.        return;
  1122.  
  1123.    /* OPEN FILES */
  1124.    fileptr = fopen(DATAFILE,"r");
  1125.    if ( fileptr == NULL )
  1126.        cleanExit("Couldn't open data file.");
  1127.    tempptr = fopen(TEMPFILE,"w");
  1128.    if ( tempptr == NULL )
  1129.    {
  1130.        fclose(fileptr);
  1131.        fileptr = 0L;
  1132.        remove(TEMPFILE);
  1133.        EasyRequest(window, &myES, NULL, "Couldn't open temporary file.");
  1134.        return;
  1135.    }
  1136.    
  1137.    /* COPY THE DATA FILE UP TO THE END OF THE MEALS SECTION */
  1138.    while ((fgets(buffer,255,fileptr) != NULL) && (strncmp(buffer,"EXIT!",5) != 0))
  1139.    {
  1140.        fputs(buffer,tempptr);
  1141.    }
  1142.  
  1143.    /* END OF MEALS SECTION NOT FOUND !!!!!  WE HAVE A PROBLEM */
  1144.    if (strncmp(buffer,"EXIT!",5) != 0)
  1145.    {
  1146.        fclose(fileptr);
  1147.        fclose(tempptr);
  1148.        fileptr = 0L;
  1149.        tempptr = 0L;
  1150.        remove(TEMPFILE);
  1151.        EasyRequest(window, &myES, NULL, 
  1152.            "Error reading data file.  EXIT! line not found");
  1153.        return;
  1154.    }
  1155.   
  1156.    /* OKAY, LETS ADD THE MEAL */
  1157.    /* ADD MEAL NAME */   
  1158.    fputs(((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer,tempptr);
  1159.    fputc('\n',tempptr);
  1160.    GT_SetGadgetAttrs(mygad[MYGAD_MEALS],window,NULL,
  1161.             GTLV_Labels, ~0, TAG_DONE);
  1162.  
  1163.    list = AddMeal(MealList,strcat(((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer,
  1164.        strnset(buffer,' ',29-strlen(((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer))));
  1165.    
  1166.    /* NOW ADD THE ITEMS */
  1167.    for (node=(struct NameNode *)GrocList->lh_Head;
  1168.         node->nn_Node.ln_Succ ; 
  1169.         node = (struct NameNode *)node->nn_Node.ln_Succ)
  1170.    {
  1171.        for (i=0;i<31;i++)
  1172.            if (aisleId[i] == node->nn_Aisle)
  1173.                break;
  1174.        if (1 > fprintf(tempptr,
  1175.            "%s`%s`%s`%d\n",
  1176.            node->nn_Item,node->nn_Amount,
  1177.            node->nn_Size, i))
  1178.        {
  1179.            fclose(tempptr);
  1180.            fclose(fileptr);
  1181.            tempptr = 0L;
  1182.            fileptr = 0L;
  1183.            remove(TEMPFILE);
  1184.            EasyRequest(window, &myES, NULL, "Couldn't write to temp file.");
  1185.            return;
  1186.        }
  1187.        AddName(list,node->nn_Item,node->nn_Amount,node->nn_Size,
  1188.        node->nn_Aisle);
  1189.    }
  1190.    
  1191.    /* NOW COPY THE REST OF THE DATA */
  1192.    GT_SetGadgetAttrs(mygad[MYGAD_MEALS],window,NULL,
  1193.             GTLV_Labels, MealList, TAG_DONE);
  1194.  
  1195.    fputc('\n',tempptr);
  1196.    fputs("EXIT!\n",tempptr);
  1197.     while (fgets(buffer,255,fileptr) != NULL)
  1198.    {
  1199.        fputs(buffer,tempptr);
  1200.    }
  1201.  
  1202.    /* CLEAN UP FILES */
  1203.    fclose(fileptr);
  1204.    fileptr=0L;
  1205.    fclose(tempptr);
  1206.    tempptr=0L;
  1207.    remove(BACKFILE);
  1208.    rename(DATAFILE, BACKFILE);
  1209.    sprintf(buffer,"copy %s %s \012delete >nil: %s",TEMPFILE, DATAFILE, TEMPFILE);
  1210.    Execute(buffer,0L,0L);
  1211.  
  1212. }
  1213.  
  1214.  
  1215.  
  1216. /*********************************************************************
  1217. *   handle_window_events()
  1218. *
  1219. **********************************************************************/
  1220.  
  1221.  
  1222. VOID 
  1223. handle_window_events(VOID)
  1224. {
  1225. struct IntuiMessage *msg;
  1226. SHORT done;
  1227. UWORD menuNumber;
  1228. UWORD menuNum;
  1229. UWORD itemNum;
  1230. UWORD subNum;
  1231. WORD   mousex, mousey;
  1232. ULONG  class;
  1233. USHORT code;
  1234. struct MenuItem *item;
  1235. char   buffer[60];
  1236. struct MealNode *mnode;
  1237. struct NameNode *node, *nextnode;
  1238. struct List *list;
  1239. struct Gadget *gad;
  1240. char   *items, *amounts, *sizes;
  1241. BPTR   pfile;
  1242. int    i;
  1243.  
  1244. done = FALSE;
  1245. while (FALSE == done)
  1246.     {
  1247.     /* we only have one signal bit, so we do not have to check which
  1248.     ** bit broke the Wait().
  1249.     */
  1250.     Wait(1L << window->UserPort->mp_SigBit);
  1251.  
  1252.     while ( (FALSE == done) &&
  1253.             (NULL != (msg = (struct IntuiMessage *)GT_GetIMsg(window->UserPort))))
  1254.     {
  1255.         class = msg->Class;
  1256.         code  = msg->Code;
  1257.         mousex= msg->MouseX;
  1258.         mousey= msg->MouseY;
  1259.         gad   = (struct Gadget *)msg->IAddress; /*not valid for non-gadget event*/
  1260.         
  1261.         GT_ReplyIMsg(msg);
  1262.         
  1263.         switch (class)
  1264.             {
  1265.             case IDCMP_MENUPICK:
  1266.                 menuNumber = code;
  1267.                 while (menuNumber != MENUNULL) 
  1268.                     {
  1269.                     item = ItemAddress(menuStrip, menuNumber);
  1270.  
  1271.                     /* process the item here! */
  1272.                     menuNum = MENUNUM(menuNumber);
  1273.                     itemNum = ITEMNUM(menuNumber);
  1274.                     subNum  = SUBNUM(menuNumber);
  1275.  
  1276.                     /* stop if quit is selected. */
  1277.                     switch ( menuNum )
  1278.                     {
  1279.                        case 0:         /*** PROJECT ***/
  1280.                           switch ( itemNum )
  1281.                           {
  1282.                              case 0:   /* NEW */
  1283.                                  doNew();
  1284.                                  break;
  1285.                                  
  1286.                              case 1:   /* OPEN... */
  1287.                                  doOpen();
  1288.                                  break;
  1289.                              
  1290.                              case 4:   /* SAVE AS ... */
  1291.                                  savefilename[0] = '\0';    
  1292.                              case 3:   /* SAVE */
  1293.                                  doSave();
  1294.                                  break;
  1295.                              
  1296.                              case 6:   /* PRINT */
  1297.                                  doPrint();
  1298.                                  break;
  1299.                              
  1300.                              case 8:   /* ABOUT */
  1301.                                  sprintf(buffer,"%s\nBrian Gragg  Oct 1993 ",&vers[7]);
  1302.                                  EasyRequest(window, &myES, NULL,buffer);
  1303.                                  break;
  1304.                                  
  1305.                              case 10:   /* QUIT */
  1306.                                  done = TRUE;
  1307.                                  break;
  1308.                           }
  1309.                           break;
  1310.                           
  1311.                        case 1:        /*** MEALS ***/
  1312.                          switch (itemNum )
  1313.                          {
  1314.                            case 0:    /* CREATE MEAL */
  1315.                                newMeal();
  1316.                                break;
  1317.                          }
  1318.                           
  1319.                        case 2:        /*** OPTIONS ***/
  1320.                          switch (itemNum )
  1321.                          {
  1322.                            case 0:    /* SCROLLING LIST */
  1323.                                break;
  1324.                          }
  1325.                     }           
  1326.                                
  1327.                     menuNumber = item->NextSelect;
  1328.                     }
  1329.                 break;
  1330.             
  1331.             case IDCMP_GADGETUP:
  1332.                switch (gad->GadgetID)
  1333.                {
  1334.                    case MYGAD_MEALS:
  1335.                        GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  1336.                                GTLV_Labels, ~0, TAG_DONE);
  1337.                        if ((mnode = (struct MealNode *)FindNode(MealList,code))==NULL)
  1338.                            break;    /* not a valid mnode */
  1339.                        list = mnode->nn_MealItem;
  1340.                        if (list->lh_TailPred == (struct Node *)list)
  1341.                            break;  /* empty list */
  1342.                        for (node=(struct NameNode *)list->lh_Head ; 
  1343.                               node->nn_Node.ln_Succ ; 
  1344.                               node = (struct NameNode *)node->nn_Node.ln_Succ)
  1345.                            AddItem(GrocList,node->nn_Item,node->nn_Amount,
  1346.                                            node->nn_Size,node->nn_Aisle);
  1347.                        GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  1348.                                GTLV_Labels, GrocList, TAG_DONE);
  1349.                        currentGroc = NOITEM;
  1350.                        ActivateGadget(mygad[MYGAD_ITEM],window,NULL);
  1351.                        break;
  1352.                         
  1353.                    case MYGAD_ILIST:
  1354.                        if (NULL == 
  1355.                          (node = (struct NameNode *)FindNode(ItemList,code)))
  1356.                            break;    /* not a valid node */
  1357.                        node->nn_ListPos = code;
  1358.                        getItem(node);
  1359.                        break;
  1360.                        
  1361.                    case MYGAD_ITEM:
  1362.                        if (code == 0x5F)   /* HELP key */
  1363.                        {
  1364.                            node = findBestFit(((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer);
  1365.                            if (node != NULL) 
  1366.                            {
  1367.                                getItem(node);
  1368.                                GT_SetGadgetAttrs(mygad[MYGAD_ILIST],window,NULL,
  1369.                                           GTLV_Top, node->nn_ListPos, TAG_DONE);      
  1370.                            }
  1371.                            break;
  1372.                        }
  1373.                    case MYGAD_AMOUNT:
  1374.                    case MYGAD_SIZE:
  1375.                        if (code == 9) break;  /* ignore tab key */
  1376.                        items = ((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer;
  1377.                        amounts = ((struct StringInfo *)mygad[MYGAD_AMOUNT]->SpecialInfo)->Buffer;
  1378.                        sizes = ((struct StringInfo *)mygad[MYGAD_SIZE]->SpecialInfo)->Buffer;
  1379.  
  1380.                        if ((strlen(items) < 3) || (strlen(amounts) < 0) ||
  1381.                            (strlen(sizes) < 1) || (currentAisle == NOITEM))
  1382.                        {
  1383.                            DisplayBeep(myscreen);
  1384.                            break;
  1385.                        }
  1386.                            
  1387.                        GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  1388.                                GTLV_Labels, ~0, TAG_DONE);
  1389.                        AddItem(GrocList, items, amounts, sizes, currentAisle);
  1390.                           
  1391.                        GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  1392.                                GTLV_Labels, GrocList, TAG_DONE);
  1393.                        currentGroc = NOITEM;
  1394.                        /* now clear the string gadgets */
  1395.                        GT_SetGadgetAttrs(mygad[MYGAD_ITEM],window,NULL,
  1396.                                GTST_String, "", TAG_DONE);
  1397.                        GT_SetGadgetAttrs(mygad[MYGAD_AMOUNT],window,NULL,
  1398.                                GTST_String, "", TAG_DONE);
  1399.                        GT_SetGadgetAttrs(mygad[MYGAD_SIZE],window,NULL,
  1400.                                GTST_String, "", TAG_DONE);
  1401.                        GT_SetGadgetAttrs(mygad[MYGAD_AISLE],window,NULL,
  1402.                                GTLV_Selected, NOITEM, TAG_DONE);
  1403.                        ActivateGadget(mygad[MYGAD_ITEM],window,NULL);
  1404.                        currentAisle = NOITEM;
  1405.                        break;
  1406.                        
  1407.                    case MYGAD_AISLE:
  1408.                        currentAisle = code;
  1409.                        ActivateGadget(mygad[MYGAD_AMOUNT],window,NULL);
  1410.                        break;
  1411.                        
  1412.                    case MYGAD_EDIT:
  1413.                        if (NULL == 
  1414.                          (node = (struct NameNode *)FindNode(GrocList,currentGroc)))
  1415.                            break;    /* not a valid node */
  1416.                        GT_SetGadgetAttrs(mygad[MYGAD_ITEM],window,NULL,
  1417.                                GTST_String, node->nn_Item, TAG_DONE);
  1418.                        GT_SetGadgetAttrs(mygad[MYGAD_AMOUNT],window,NULL,
  1419.                                GTST_String, node->nn_Amount, TAG_DONE);
  1420.                        GT_SetGadgetAttrs(mygad[MYGAD_SIZE],window,NULL,
  1421.                                GTST_String, node->nn_Size, TAG_DONE);
  1422.                        GT_SetGadgetAttrs(mygad[MYGAD_AISLE],window,NULL,
  1423.                                GTLV_Selected, node->nn_Aisle, TAG_DONE);
  1424.                        ActivateGadget(mygad[MYGAD_AMOUNT],window,NULL);
  1425.                        currentAisle = node->nn_Aisle;
  1426.                    case MYGAD_DELETE:
  1427.                        if (NULL == 
  1428.                           (node = (struct NameNode *)FindNode(GrocList,currentGroc)))
  1429.                            break;    /* not a valid node */
  1430.                        GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  1431.                                GTLV_Labels, ~0, TAG_DONE);
  1432.                        Remove((struct Node *)node);
  1433.                        GT_SetGadgetAttrs(mygad[MYGAD_GLIST],window,NULL,
  1434.                                GTLV_Labels, GrocList, TAG_DONE);
  1435.                        FreeMem(node,sizeof(struct NameNode));
  1436.                        currentGroc = NOITEM;
  1437.                        ActivateGadget(mygad[MYGAD_ITEM],window,NULL);
  1438.                        break;
  1439.   
  1440.                    case MYGAD_GLIST:
  1441.                        currentGroc = code;
  1442.                        ActivateGadget(mygad[MYGAD_ITEM],window,NULL);
  1443.                        break;
  1444.                        
  1445.                    case MYGAD_SORT:
  1446.                    case MYGAD_SORTNAME:
  1447.                        doSort((int)gad->GadgetID);
  1448.                        break;
  1449.                    
  1450.                    case MYGAD_ADD:
  1451.                        items = ((struct StringInfo *)mygad[MYGAD_ITEM]->SpecialInfo)->Buffer;
  1452.                        amounts = ((struct StringInfo *)mygad[MYGAD_AMOUNT]->SpecialInfo)->Buffer;
  1453.                        sizes = ((struct StringInfo *)mygad[MYGAD_SIZE]->SpecialInfo)->Buffer;
  1454.  
  1455.                        if ((strlen(items) < 3) || (strlen(amounts) < 1) ||
  1456.                            (strlen(sizes) < 1) || (currentAisle == NOITEM))
  1457.                        {
  1458.                            DisplayBeep(myscreen);  /* bad data */
  1459.                            break;
  1460.                        }
  1461.                        
  1462.                        /* Save the new item to the DATAFILE */
  1463.                        
  1464.                        if (!(pfile = Open(DATAFILE,MODE_OLDFILE)))
  1465.                        {
  1466.                            EasyRequest(window, &myES, NULL, "Couldn't open data file");
  1467.                            break;
  1468.                        }
  1469.                        
  1470.                        Seek(pfile,0,OFFSET_END);
  1471.                        for (i = 0; i < 30; i++)
  1472.                            if (aisleId[i] == currentAisle)
  1473.                                break;
  1474.                        sprintf(buffer, "%s`%s`%s`%d\n", items, amounts,
  1475.                                    sizes, i);
  1476.                        Write(pfile, buffer, strlen(buffer));
  1477.                        Close(pfile);
  1478.                        
  1479.                        /* Update the Item List */
  1480.                        GT_SetGadgetAttrs(mygad[MYGAD_ILIST],window,NULL,
  1481.                                GTLV_Labels, ~0, TAG_DONE);
  1482.                        
  1483.                        AddName(ItemList, items, amounts, sizes, currentAisle);
  1484.                           
  1485.                        GT_SetGadgetAttrs(mygad[MYGAD_ILIST],window,NULL,
  1486.                                GTLV_Labels, ItemList, TAG_DONE);
  1487.                        ActivateGadget(mygad[MYGAD_AMOUNT],window,NULL);
  1488.                        break;
  1489.                        
  1490.                    default:
  1491.                        break;
  1492.                }
  1493.             case IDCMP_REFRESHWINDOW:
  1494.                GT_BeginRefresh(window);
  1495.                GT_EndRefresh(window, TRUE);
  1496.                break;
  1497.    
  1498.             default:
  1499.                break;
  1500.                
  1501.             }
  1502.         }
  1503.     }
  1504. }
  1505.  
  1506.